package com.fingard.dsp.bank.directbank.alipay01;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringEscapeUtils;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayInsAutoFeeReceiveConfirmRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayInsAutoFeeReceiveConfirmResponse;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IOtherElse;
import com.fingard.dsp.bank.reqrespobj.otherelse.ReqOtherElse;
import com.fingard.dsp.bank.reqrespobj.otherelse.RetAtsOtherElse;
import com.fingard.text.StringHelper;

public class ALIPAY01OtherElse extends ALIPAY01Base implements IOtherElse {
	@Override
	public RetAtsOtherElse d_else(ReqOtherElse p_reqElse) throws Exception {
		String transType = p_reqElse.reqHeader.transType;

		if ("Sign".equals(transType)) {
			String commandCode = p_reqElse.reqHeader.commandCode;
			
			// 即时到账
			if ("GW01".equals(commandCode)) {
				return signGW(p_reqElse);
			} 
			
			// WAP支付
			if ("WAP01".equals(commandCode)) {
				return signWAP(p_reqElse);
			}
		} else if (("VerifySign").equals(transType)) {
			return verifySign(p_reqElse);
		} else if (("Notify").equals(transType)) {
			return activeNotify(p_reqElse);
		} else {
			RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

			retAts.retHashMap = new HashMap<String, String>();
			retAts.retHashMap.put("RespCode", "-1");
			retAts.retHashMap.put("RespInfo", "未知的TransType：" + transType);

			return retAts;
		}
		
		return null;
	}
	
	public RetAtsOtherElse signGW(ReqOtherElse p_reqElse) {
		RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

		retAts.retHashMap = new HashMap<String, String>();
		try {
			logIsExist();

			String ownAct = "";
			if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
				ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
			}
			
			String bizContent = "";
			if (p_reqElse.reqHashMap.containsKey("BizContent")) {
				bizContent = p_reqElse.reqHashMap.get("BizContent");
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "缺失'BizContent'");
				return retAts;
			}

			ActSetItem actItem = getBankConfig().getActSetItem(ownAct, "unifiedorder");
			if (actItem != null) {
				AlipayClient alipayClient = new DefaultAlipayClient(bankFront.serverURL, actItem.appId, 
						actItem.ownKeyStorePath, "json", getCharset(), actItem.oppCertFilePath, "RSA");

				AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();

				alipayRequest.setReturnUrl(actItem.returnURL);
				alipayRequest.setNotifyUrl(actItem.notifyURL);
				alipayRequest.setBizContent(bizContent);
				
				WriteBankUrlLogLn(bankFront.serverURL);
				WriteBankLogStep2(alipayRequest.getBizContent());
				
				String result = alipayClient.pageExecute(alipayRequest).getBody();
				WriteBankLogStep3(result);

				if (result.length() > 0) {
					retAts.retHashMap.put("RespCode", "0");
					retAts.retHashMap.put("RespInfo", "签名成功");
					retAts.retHashMap.put("Result", result);
				} else {
					retAts.retHashMap.put("RespCode", "-1");
					retAts.retHashMap.put("RespInfo", "签名失败");
				}
			} else {
				retAts.retHashMap.put("RespCode", "0");
				retAts.retHashMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息");
				retAts.retHashMap.put("Result", "");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.retHashMap.put("RespCode", "-1");
			retAts.retHashMap.put("RespInfo", ex.getMessage());
			WriteBankLogLn(ex);
		}

		return retAts;
	}
	
	public RetAtsOtherElse signWAP(ReqOtherElse p_reqElse) {
		RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

		retAts.retHashMap = new HashMap<String, String>();
		try {
			logIsExist();

			String ownAct = "";
			if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
				ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
			}
			
			String bizContent = "";
			if (p_reqElse.reqHashMap.containsKey("BizContent")) {
				bizContent = p_reqElse.reqHashMap.get("BizContent");
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "缺失'BizContent'");
				return retAts;
			}

			ActSetItem actItem = this.getBankConfig().getActSetItem(ownAct, "unifiedorder");
			if (actItem != null) {
				AlipayClient alipayClient = new DefaultAlipayClient(bankFront.serverURL, actItem.appId, 
						actItem.ownKeyStorePath, "json", getCharset(), actItem.oppCertFilePath, "RSA");

				AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
				
				@SuppressWarnings("unchecked")
				Map<String,String> params = (Map<String,String>)JSON.parse(bizContent); 
				model.setOutTradeNo(params.get("out_trade_no"));
				model.setSubject(params.get("subject"));
				model.setTotalAmount(params.get("total_amount"));
				model.setBody(params.get("body"));
				model.setProductCode(params.get("product_code"));
				
				AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
				alipayRequest.setReturnUrl(actItem.returnURL);
				alipayRequest.setNotifyUrl(actItem.notifyURL);
				alipayRequest.setBizModel(model);
				
				WriteBankUrlLogLn(bankFront.serverURL);
				
				String result = alipayClient.pageExecute(alipayRequest).getBody();
				WriteBankLogStep3(result);

				if (result.length() > 0) {
					retAts.retHashMap.put("RespCode", "0");
					retAts.retHashMap.put("RespInfo", "签名成功");
					retAts.retHashMap.put("Result", result);
				} else {
					retAts.retHashMap.put("RespCode", "-1");
					retAts.retHashMap.put("RespInfo", "签名失败");
				}
			} else {
				retAts.retHashMap.put("RespCode", "0");
				retAts.retHashMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息");
				retAts.retHashMap.put("Result", "");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.retHashMap.put("RespCode", "-1");
			retAts.retHashMap.put("RespInfo", ex.getMessage());
			WriteBankLogLn(ex);
		}

		return retAts;
	}

	public RetAtsOtherElse verifySign(ReqOtherElse p_reqElse) {
		RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

		retAts.retHashMap = new HashMap<String, String>();
		try {
			logIsExist();

			String ownAct = "";
			if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
				ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
			}
			
			String plain = "";
			WriteBankLogLn("转义前");
			if (p_reqElse.reqHashMap.containsKey("Plain")) {
				plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("Plain")).replace("&quot;","\"");
				WriteBankLogLn("转义后的plain："+plain);
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "缺失验签原始串");

				return retAts;
			}

			ActSetItem actItem = this.getBankConfig().getActSetItem(ownAct, "unifiedorder");
			if (actItem != null) {
				Map<String, String> params = convertToMap(plain);

				// 执行验签
				String signType = "RSA";
				if ("APP01".equals(p_reqElse.reqHashMap.get("CommandCode")) || "WAP01".equals(p_reqElse.reqHashMap.get("CommandCode"))) {
					signType = "RSA2";
				}
            	boolean useSignType = getBankConfig().getValueAsBool("useSignType");
            	if (useSignType) {
            		signType = actItem.signType;
            	}
				
				boolean signVerified = AlipaySignature.rsaCheckV1(params, actItem.oppCertFilePath, getCharset(), signType);
				if (signVerified) {
					retAts.retHashMap.put("RespCode", "0");
					retAts.retHashMap.put("RespInfo", "验签通过");
				} else {
					retAts.retHashMap.put("RespCode", "-1");
					retAts.retHashMap.put("RespInfo", "验签失败");
				}
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.retHashMap.put("RespCode", "-1");
			retAts.retHashMap.put("RespInfo", ex.getMessage());
			WriteBankLogLn(ex);
		}

		return retAts;
	}
	
	/**
	 * 主动通知
	 * 
	 * @param p_reqElse 通知请求对象
	 * @return 通知响应对象
	 */
	public RetAtsOtherElse activeNotify(ReqOtherElse p_reqElse) {
		RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
		retAts.retHashMap = new HashMap<String, String>();
		
		try {
			logIsExist();

			String ownAct = "";
			if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
				ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
			}

			ActSetItem actItem = getBankConfig().getActSetItem(ownAct, "unifiedorder");
			if (actItem != null) {
				String signType = "RSA";
				if ("WAP01".equals(p_reqElse.reqHashMap.get("CommandCode"))) {
					signType = "RSA2";
				}
				boolean useSignType = getBankConfig().getValueAsBool("useSignType");
            	if (useSignType) {
            		signType = actItem.signType;
            	}
				AlipayClient alipayClient = new DefaultAlipayClient(bankFront.serverURL, actItem.appId, 
						actItem.ownKeyStorePath, "json", getCharset(), actItem.oppCertFilePath, signType);
				
				AlipayInsAutoFeeReceiveConfirmRequest alipayRequest = new AlipayInsAutoFeeReceiveConfirmRequest();
				alipayRequest.setApiVersion("1.0");
				alipayRequest.setBizContent("{"+
						"\"out_biz_no\":\""+p_reqElse.reqHashMap.get("RdSeq")+"\","+
						"\"trade_amount\":"+StringHelper.amountMultiply100(p_reqElse.reqHashMap.get("Amount"))+
						"}");
				WriteBankUrlLogLn(bankFront.serverURL);
				WriteBankLogStep2(alipayRequest.getBizContent());
				
				AlipayInsAutoFeeReceiveConfirmResponse response = alipayClient.execute(alipayRequest);
				WriteBankLogStep3(response.getBody());
				if ("10000".equals(response.getCode())) {
					retAts.retHashMap.put("RespCode", "0");
					retAts.retHashMap.put("RespInfo", "通知成功");
				} else {
					boolean isBreak = false;
					int notifySleepTime = getBankConfig().getValueAsInt("notifySleepTime");
					for (int i = 1; i <= 3; i++) {
						Thread.sleep(notifySleepTime * i * 1000);
						
						response = alipayClient.execute(alipayRequest);
						WriteBankLogStep3(response.getBody());
						if ("10000".equals(response.getCode())) {
							retAts.retHashMap.put("RespCode", "0");
							retAts.retHashMap.put("RespInfo", "通知成功");
							isBreak = true;
						} else {
							i++;
						}
					}
					if (!isBreak) {
						retAts.retHashMap.put("RespCode", "-1");
						retAts.retHashMap.put("RespInfo", "通知失败");
					}
				}
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "未找到账号:[" + ownAct + "]商户配置信息!");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.retHashMap.put("RespCode", "-1");
			retAts.retHashMap.put("RespInfo", ex.getMessage());
			WriteBankLogLn(ex);
		}

		return retAts;
	}
}
